const app = getApp();
const numConversion = require('../../utils/numConversion.js');
const {
  http_request
} = require("../../utils/request");
const {
  getStatus,
  analysisMessage,
  getPNPStatus,
  setUpdate0,
  ifUpdate,
  transferBin,
  setPnpStatus,
  insertPileInfo,
  emptyData
} = require("../../utils/api");
const errorMap = {
  0: "状态良好",
  1: "漏电保护",
  2: "CP故障",
  3: "过压故障",
  4: "欠压故障",
  5: "过流故障",
  6: "接地检测",
  7: "急停按下",
  8: "短路故障",
  9: "过温检测",
  10: "温度芯片故障",
  11: "计量芯片故障",
  12: "漏电自检故障",
  13: "继电器粘连故障",
  14: "输出短路",
  15: "入网失败（信号差）"
};
Page({
  data: {
    chargingPileId: null,
    deviceId: null,
    serviceId: null,
    characteristicId: null,
    isConnected: false,
    buffer: '',
    completeDataArray: [],
    voltage: '',
    current: '',
    power: '',
    directUse: null,
    ota: false,
    showUpdateDialog: false,
    receivedData: [], // 存储所有接收到的数据
    isUpdating: false,
    firmwareData: {
      count: 0,
      chunks: [],
      currentIndex: 0
    },
    updatePhase: 'idle',
    currentChunkIndex: 0,
    lastReceivedData: '',
    isWaitingAck: false,
    ackTimeout: null, // 超时计时器
    ackTimeoutLimit: 15000, // 5秒超时（可配置）
    isTransmissionActive: true, // 传输总开关
    showReservePopup: false,
    reserveTime: '',     // 当前选择时间
    minTime: '',         // 当前时间（用于限制）
    hasReserved: false,
    isReserveDisabled: false, // 是否禁用预约按钮
    CP:'',
    error: 0,
    errorCode: 0,
  },

  onLoad(e) {
    const devicedIdPrevious = e.connectedDeviceId
    console.info("上一个页面传过来的devicedId为：",devicedIdPrevious)
    const chargingPileId = wx.getStorageSync('chargingPileId');
    if (!chargingPileId) {
      wx.showToast({
        title: '设备未连接',
        icon: 'none'
      });
      return;
    }
    console.info('连接设备chargingPileId:', chargingPileId);
    this.setData({
      chargingPileId: chargingPileId
    });
    this.initBle(); 
    this.openBLEConnection(devicedIdPrevious);
  },

  onUnload() {
    wx.offBLECharacteristicValueChange(this.handleBLEDataChange);
    console.info('已清除蓝牙数据监听');
  },
// 初始化充电桩信息（调用接口）
  initBle() {
    http_request(insertPileInfo, { 
      chargingPileId: this.data.chargingPileId 
    }, 'POST')
      .then(res => {
        console.info(res)
        if (res.code === 0) {
          console.info("蓝牙设备初始化成功！");
          this.decidingOta()
          this.getpnpStatus()
        }
      })
      .catch(err => console.error("蓝牙初始化失败", err));
      console.info("-------- 啊啊啊啊啊啊--------")
  },
  getpnpStatus() {
    http_request(getPNPStatus, {
        chargingPileId: this.data.chargingPileId
      }, 'GET')
      .then(res => {
        const directUseValue = res.data === 0 ? false : true;
        this.setData({
          directUse: directUseValue
        });
      })
      .catch(err => {
        console.error("PNP状态获取失败:", err);
      });
  },
  pnpUsing() {
    if (this.data.directUse === true) {
      this.send2BleData(this.data.deviceId, this.data.serviceId, this.data.characteristicId, 'PNP=0');
      this.setPnpStatus(0);
      this.setData({
        directUse: false
      })
      console.info("PnpStatus状态为0")
    } else {
      this.send2BleData(this.data.deviceId, this.data.serviceId, this.data.characteristicId, 'PNP=1');
      this.setPnpStatus(1)
      this.setData({
        directUse: true
      })
      console.info("PnpStatus状态为1")
    }
  },
  decidingOta() {
    http_request(ifUpdate, {
        chargingPileId: this.data.chargingPileId
      }, 'GET')
      .then(res => {
        if (res.data === true) {
          wx.showModal({
            title: '升级通知',
            content: '检测到您的充电桩有新的版本需要更新，请点击右下角远程升级开关进行升级哦！',
            showCancel: false, // 不显示取消按钮
            confirmText: '知道了', // 显示确定按钮
            success: (res) => {
              if (res.confirm) {
                console.log('用户已知晓需要升级的消息');
              }
            }
          });
        } else {
          console.info("未检测到新的升级包");
        }
      })
      .catch(err => console.error("更新检查失败:", err));
  },
  otaUsing() {
    if (this.data.ota === false) {
      http_request(ifUpdate, {
          chargingPileId: this.data.chargingPileId
        }, 'GET')
        .then(res => {
          if (res.data === true) {
            this.setData({
              showUpdateDialog: true,
              ota: true
            });
            this.send2BleData(this.data.deviceId, this.data.serviceId, this.data.characteristicId, 'beginCharging');
          } else {
            this.setData({
              showUpdateDialog: false,
              ota: false
            });
            wx.showToast({
              title: '当前设备完好且是最新版本，您无需更新哦',
              icon: 'none'
            });
            console.info("当前设备完好且是最新版本，无需更新");
          }
        })
        .catch(err => console.error("更新检查失败:", err));
    } else {
      this.setData({
        showUpdateDialog: true,
      });
    }
  },
  setPnpStatus(code) {
    console.info(code)
    http_request(setPnpStatus, {
        chargingPileId: this.data.chargingPileId,
        PNP_SW: code
      }, 'POST')
      .then(res => {
        if (res) {
          console.info(res)
          console.info("NPN状态已更新")
        }
      })
      .catch(err => console.error("NPN状态更新失败:", err));
  },

  openBLEConnection(deviceId) {
    wx.getConnectedBluetoothDevices({
      success: (res) => {
        console.info('已连接的设备:', res.devices);
        const device = res.devices.find(d => d.deviceId === deviceId);
        if (device) {
          console.info('设备已连接，直接获取服务');
          this.setData({
            isConnected: true
          });
          this.getBLEDeviceServices(deviceId);
        } else {
          this.createBLEConnection(deviceId);
        }
      },
      fail: (err) => console.error('获取已连接设备失败:', err),
    });
  },

  createBLEConnection(deviceId) {
    wx.createBLEConnection({
      deviceId,
      success: () => {
        console.info('蓝牙设备连接成功');
        this.setData({
          isConnected: true
        });
        this.getBLEDeviceServices(deviceId);
      },
      fail: (err) => console.error('蓝牙连接失败:', err),
    });
  },

  getBLEDeviceServices(deviceId) {
    wx.getBLEDeviceServices({
      deviceId,
      success: (res) => {
        console.info('设备服务:', res.services);
        if (res.services.length > 0) {
          const serviceId = res.services[0].uuid;
          this.getBLEDeviceCharacteristics(deviceId, serviceId);
        } else {
          wx.showToast({
            title: '未找到服务',
            icon: 'none'
          });
        }
      },
      fail: (err) => console.error('获取设备服务失败:', err),
    });
  },

  getBLEDeviceCharacteristics(deviceId, serviceId) {
    wx.getBLEDeviceCharacteristics({
      deviceId,
      serviceId,
      success: (res) => {
        if (res.characteristics.length > 0) {
          console.info('lalalla', deviceId);
          const characteristicId = res.characteristics[0].uuid;
          this.setData({
            deviceId: deviceId,
            serviceId: serviceId,
            characteristicId: characteristicId
          });
          console.info("获取蓝牙三个特征值的第一个deviceId为：", deviceId)
          console.info("获取蓝牙三个特征值的第二个serviceId为：", serviceId)
          console.info("获取蓝牙三个特征值的第三个characteristicId为：", characteristicId)
          this.notifyBLECharacteristicValueChange(deviceId, serviceId, characteristicId);
        } else {
          wx.showToast({
            title: '未找到特征值',
            icon: 'none'
          });
        }
      },
      fail: (err) => console.error('获取特征值失败:', err),
    });
  },

  notifyBLECharacteristicValueChange(deviceId, serviceId, characteristicId) {
    wx.notifyBLECharacteristicValueChange({
      deviceId,
      serviceId,
      characteristicId,
      state: true,
      success: () => {
        console.info('特征值通知已启用:', characteristicId);
        this.listenBLECharacteristicValueChange();
      },
      fail: (err) => {
        console.error('启用通知失败:', err);
        wx.showToast({
          title: '启用通知失败',
          icon: 'none'
        });
      },
    });
  },

  listenBLECharacteristicValueChange() {
    console.info("开始监听数据")
    wx.onBLECharacteristicValueChange(async (res) => {
      const partData = this.arrayBufferToString(res.value);
      if (this.data.updatePhase !== 'idle') { // 固件升级阶段
        console.info('固件升级数据:', partData);
        this.handleBLEDataChange(partData); // 直接处理当前数据块
      } else { // 正常模式处理JSON
        const newBuffer = this.data.receivedData + partData;
        this.setData({
          receivedData: newBuffer
        });
        if (newBuffer.trim().startsWith('{') && newBuffer.trim().endsWith('}')) {
          await this.sendDataToServer(newBuffer);
          this.handleChargingPileData();
          this.setData({
            receivedData: ''
          }); // 处理完成后清空
        }
      }
    });
  },
  handleChargingPileData() {
    http_request(getStatus, {
        chargingPileId: this.data.chargingPileId
      }, "GET")
      .then(res => {
        if (res.data) {
          const cpValue = res.data.CP;
          const errorCode = res.data.error || 0;
          const isInvalidCP = cpValue === 6 || cpValue === '' || cpValue === null || cpValue === undefined;
          this.setData({
            voltage: res.data.UABC || 0,
            current: res.data.IABC || 0,
            power: res.data.PABC || 0,
            CP: cpValue,
            error: errorCode,
            errorText: errorMap[errorCode] || "未知状态",
            isReserveDisabled: isInvalidCP
          });
          console.info("CP值为", cpValue);
        } else {  
          wx.showToast({
            title: '请求失败，请检查充电桩 ID',
            icon: 'none'
          });
        }
      })
      .catch(err => wx.showToast({
        title: '网络请求失败',
        icon: 'none'
      }));
  },
  sendDataToServer(data) {
    http_request(analysisMessage, data, "POST", {
        "Content-Type": "application/json"
      })
      .then(res => console.info('数据发送成功:', res))
      .catch(err => wx.showToast({
        title: '数据上传失败',
        icon: 'none'
      }));
  },
  // 处理接收到的蓝牙数据
  handleBLEDataChange(receivedValue) {
    this.setData({
      receivedData: [receivedValue] // 用数组包裹，表示只保留最新一条
    });
    console.log('收到数据:', receivedValue);
    switch (this.data.updatePhase) {
      case 'VER_OK':
        if (this.containsTarget([receivedValue], 'VER:OK')) {
          this.onVerOkReceived();
        } else {
          console.warn("警告！警告！数据存在问题")
        }
        break;

      case 'NUM_OK':
        if (this.containsTarget([receivedValue], 'NUM:OK')) {
          this.onNumOkReceived();
        }
        break;

      case 'Sending':
        if (this.containsTarget([receivedValue], 'ACK:OK')) {
          this.onChunkAckReceived();
        } else if (this.containsTarget([receivedValue], 'ANCK:OK')) {
          this.onChunkNackReceived();
        }
        break;

      case 'AECK':
        if (this.containsTarget([receivedValue], 'AECK')) {
          clearTimeout(this.data.terminationTimeout); // 清除超时监控
          this.onUpdateFinished();
        }
        break;
    }
  },
  handleConfirmUpdate() {
    this.setData({
      showUpdateDialog: false
    });
    setTimeout(() => {
      this.send2BleData(this.data.deviceId, this.data.serviceId, this.data.characteristicId, 'VER:VER-1.0.0-2025-09-09-19.00');
    }, 2000);
    this.prepareFirmwareUpdate();
  },
  // 准备固件更新
  prepareFirmwareUpdate() {
    http_request(transferBin, {
        chargingPileId: this.data.chargingPileId
      }, 'GET')
      .then(res => {
        if (res.data.count) {
          console.info(res)
          this.setData({
            firmwareData: {
              count: res.data.count,
              chunks: res.data.resultChunks
            },
          }, () => this.startFirmwareUpdate());
        }
      })
      .catch(err => console.error("获取固件失败:", err));
  },

  // 启动固件更新
  startFirmwareUpdate() {
    this.setData({
      isUpdating: true,
      isTransmissionActive: true, // 确保传输开关打开
      updatePhase: 'VER_OK',
      currentChunkIndex: 0,
      receivedData: [],
      ackTimeout: null
    });

  },
  // VER:OK 收到后的处理
  onVerOkReceived() {
    this.setData({
      updatePhase: 'NUM_OK'
    });
    console.info("lalalallalalla",this.data.updatePhase)
    this.send2BleData(
      this.data.deviceId,
      this.data.serviceId,
      this.data.characteristicId,
      'VERMul:' + this.data.firmwareData.count.toString()
    );
  },

  // NUM:OK 收到后的处理
  onNumOkReceived() {
    this.setData({
      updatePhase: 'Sending',
      currentChunkIndex: 0
    });
    console.info("bababbababa",this.data.updatePhase)
    this.sendNextChunk();
  },

  sendNextChunk() {
    if (!this.data.isTransmissionActive) {
      console.error('传输已被强制终止');
      return;
    }
    if (this.data.currentChunkIndex >= this.data.firmwareData.chunks.length) {
      this.onAllChunksSent();
      return;
    }
    // if (this.data.currentChunkIndex >= 3) {
    //   this.onAllChunksSent();
    //   return;
    // }
    if (this.data.isWaitingAck) return;
    // 清除旧定时器
    if (this.data.ackTimeout) {
      clearTimeout(this.data.ackTimeout);
    }
    const chunk = this.data.firmwareData.chunks[this.data.currentChunkIndex];
    console.log(`发送块 ${this.data.currentChunkIndex + 1} [${new Date().toLocaleTimeString()}]`);
    this.setData({
      isWaitingAck: true
    });
    // 设置新的超时监控
    this.data.ackTimeout = setTimeout(() => {
      if (this.data.isWaitingAck) { // 仍然在等待状态
        console.error(`🚨 数据块 ${this.data.currentChunkIndex + 1} 响应超时（5秒）`);
        this.abortTransfer();
      }
    }, this.data.ackTimeoutLimit);
    this.send2BleMoreData(
      this.data.deviceId,
      this.data.serviceId,
      this.data.characteristicId,
      chunk
    );
  },
  onChunkAckReceived() {
    clearTimeout(this.data.ackTimeout);
    console.log(`✅ 块 ${this.data.currentChunkIndex + 1} 确认成功`);
    this.setData({
      isWaitingAck: false,
      currentChunkIndex: this.data.currentChunkIndex + 1
    });
    if (this.data.isTransmissionActive) {
      this.sendNextChunk();
    }
  },

  onChunkNackReceived() {
    clearTimeout(this.data.ackTimeout);
    console.warn(`🔄 块 ${this.data.currentChunkIndex + 1} 重发请求`);
    this.setData({
      isWaitingAck: false
    });
    if (this.data.isTransmissionActive) {
      this.sendNextChunk();
    }
  },
  // 在所有数据块发送完成后调用
  onAllChunksSent() {
    console.log('🎉 所有数据块发送完成');
    this.setData({
      updatePhase: 'AECK'
    });

    // 发送结束指令（20个AA）
    this.sendTerminationSequence();
  },
  // 发送结束指令方法
  sendTerminationSequence() {
    const terminationCommand = Array(20).fill('AA').join(',');
    console.log('发送结束指令:', terminationCommand);

    this.send2BleData(
      this.data.deviceId,
      this.data.serviceId,
      this.data.characteristicId,
      terminationCommand
    );

    // 启动结束确认超时监控
    this.data.terminationTimeout = setTimeout(() => {
      if (this.data.updatePhase === 'AECK') {
        console.error('结束指令未收到确认');
        this.abortTransfer('结束确认超时');
      }
    }, 15000); // 5秒超时
  },
  // 强制终止传输
  abortTransfer() {
    console.error('### 正在终止固件传输 ###');
    clearTimeout(this.data.ackTimeout);
    this.setData({
      isTransmissionActive: false,
      isUpdating: false,
      isWaitingAck: false,
    });
    this.send2BleData(this.data.deviceId,this.data.serviceId,this.data.characteristicId,'Timeout');
    this.onUpdateFailed('传输超时终止');
    this.setData({
      ota: false,
      receivedData:'',
      updatePhase: 'idle'
    });
  },

  onUpdateFailed(reason) {
    wx.showToast({
      title: `更新失败: ${reason}`,
      icon: 'none',
      duration: 3000,
      updatePhase: 'idle', // 关键重置点
    });
  },
  //更新完成处理
  onUpdateFinished() {
    console.log('✔️ 固件更新成功完成');
    this.setData({
      ota: false,
      receivedData: '',
      updatePhase: 'idle', // 关键重置点
    })
    console.info(this.data.updatePhase)
    // 发送 HTTP 请求通知服务器更新完成
    http_request(setUpdate0, {
      chargingPileId: this.data.chargingPileId,
      updateStatus: 0
    }, 'POST')
      .then(res => {
        if (res.code === 0 && res.msg) {
          console.info('数据库OTA更新成功');
        }
      })
      .catch(err => {
        console.error("数据库OTA更新失败:", err);
      });

    // 清除定时器
    clearTimeout(this.data.terminationTimeout);

    // 更新页面状态
    this.setData({
      isUpdating: false,
      isTransmissionActive: false,
    });

    // 显示成功提示
    wx.showToast({
      title: '更新成功',
      icon: 'success',
      duration: 2000
    });
  },
  send2BleData(deviceId, serviceId, characteristicId, data) {
    const buffer = this.stringToArrayBuffer(data);
    wx.writeBLECharacteristicValue({
      deviceId,
      serviceId,
      characteristicId,
      value: buffer,
      success: () => {
        console.log('发送数据成功:', data);
      },
      fail: (err) => console.error('发送数据失败:', err)
    });
  },
  send2BleMoreData(deviceId, serviceId, characteristicId, data) {
    const maxChunkSize = 20; // 每次发送的最大字节数，具体根据设备限制
    const chunks = this.splitDataIntoChunks(data, maxChunkSize);

    const sendNextChunk = (index) => {
      if (index >= chunks.length) {
        return;
      }
      const chunk = chunks[index];
      const buffer = this.stringToArrayBuffer(chunk);
      wx.writeBLECharacteristicValue({
        deviceId,
        serviceId,
        characteristicId,
        value: buffer,
        success: () => {
          sendNextChunk(index + 1); // 发送下一个块
        },
        fail: (err) => {
          console.error(`发送块 ${index + 1} 失败:`, err);
          // 如果发送失败，结束数据发送流程
        }
      });
    };
    sendNextChunk(0); // 从第一个块开始发送
  },
  splitDataIntoChunks(data, chunkSize) {
    const chunks = [];
    for (let i = 0; i < data.length; i += chunkSize) {
      chunks.push(data.slice(i, i + chunkSize));
    }
    return chunks;
  },

  // 字符串转ArrayBuffer
  stringToArrayBuffer(str) {
    const buffer = new ArrayBuffer(str.length);
    const dataView = new DataView(buffer);
    for (let i = 0; i < str.length; i++) {
      dataView.setUint8(i, str.charCodeAt(i));
    }
    return buffer;
  },

  // ArrayBuffer转字符串
  arrayBufferToString(buffer) {
    const uint8Array = new Uint8Array(buffer);
    let str = '';
    uint8Array.forEach(item => {
      str += String.fromCharCode(item);
    });
    return str;
  },

  //判断是否包含目标字符串
  containsTarget(data, target) {
    if (Array.isArray(data)) {
      return data.some(item => item.includes(target));
    } else {
      return data.includes(target);
    }
  },
  chargingBegin(){
    this.send2BleData(this.data.deviceId, this.data.serviceId, this.data.characteristicId, 'POWER_ENABLE');
  },
  handleCancelUpdate() {
    this.setData({
      showUpdateDialog: false,
      ota: false
    });
    this.send2BleData(this.data.deviceId, this.data.serviceId, this.data.characteristicId, 'cancelCharging');
  },
  stopCharging() {
    this.send2BleData(this.data.deviceId, this.data.serviceId, this.data.characteristicId, 'POWER_DISABLE');
    wx.navigateTo({
      url: `../ble/ble`,
    });
    http_request(emptyData, {
      chargingPileId: this.data.chargingPileId
    }, 'POST')
      .then(res => {
        if (res.code === 0 && res.msg) {
          console.info('充完电啦！清理数据喽！');
        }
      })
      .catch(err => {
        console.error("重置数据库失败:", err);
      });
  },

 // 打开预约弹窗
 onOpenReservePopup() {
  if (this.data.isReserveDisabled) {
    wx.showToast({
      title: '正在充电中，无法预约',
      icon: 'none'
    });
    return;
  }

  const now = new Date();
  let hour = now.getHours();
  let minute = now.getMinutes();

  // 向上取整到15分钟
  let roundedMinute = Math.ceil(minute / 15) * 15;
  if (roundedMinute >= 60) {
    roundedMinute = 0;
    hour += 1;
  }

  const minTime = `${hour.toString().padStart(2, '0')}:${roundedMinute.toString().padStart(2, '0')}`;

  this.setData({
    showReservePopup: true,
    minTime,
    reserveTime: minTime
  });
},

// 关闭弹窗
onCloseReservePopup() {
  this.setData({ showReservePopup: false });
},

// 选择时间更新
onReserveTimeChange(e) {
  this.setData({ reserveTime: e.detail.value });
},

// 点击时间框（激活 picker）
onSelectTime() {
  // 空函数激活 <picker>
},

// 确认预约
onConfirmReserve() {
  const now = new Date();
  const [hour, minute] = this.data.reserveTime.split(':').map(Number);
  const reserveTime = new Date();
  reserveTime.setHours(hour);
  reserveTime.setMinutes(minute);
  reserveTime.setSeconds(0);

  const diff = reserveTime - now;
  if (diff <= 0) {
    wx.showToast({ title: '预约时间必须大于当前时间', icon: 'none' });
    return;
  }

  const difference = Math.floor(diff / 1000); // 秒
  const command = `ALARM_TIME=${difference}`;
  this.send2BleData(this.data.deviceId, this.data.serviceId, this.data.characteristicId, command);

  wx.showToast({ title: `已预约 ${this.data.reserveTime}`, icon: 'success' });

  this.setData({
    showReservePopup: false,
    hasReserved: true
  });
},
  
});